Skip to content

fix(monaco): address timing issue in validation patch#67

Merged
johnyanarella merged 1 commit intomainfrom
topic/monaco-validation-timing
May 1, 2026
Merged

fix(monaco): address timing issue in validation patch#67
johnyanarella merged 1 commit intomainfrom
topic/monaco-validation-timing

Conversation

@johnyanarella
Copy link
Copy Markdown
Collaborator

@johnyanarella johnyanarella commented May 1, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Fixed stale diagnostic error markers that would persist in the code editor after content updates. The editor now correctly validates against the current document state rather than lingering on outdated validation results.
    • Improved consistency in document symbol mapping during code analysis operations to ensure more reliable code navigation and intelligence features.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

Updates package.json by removing a duplicate @semantic-release/github dependency declaration and reorganizing devDependencies entries. Additionally, modifies Monaco editor patches to add version validation in DiagnosticsAdapter to prevent stale model updates and refactors symbol mapping in DocumentSymbolAdapter.

Changes

Cohort / File(s) Summary
Dependency Management
package.json
Removed duplicate @semantic-release/github@12.0.6 entry and reorganized devDependencies to ensure wireit@0.14.12 remains properly declared.
Monaco Editor Patches
patches/monaco-editor.patch
Enhanced DiagnosticsAdapter to capture model versionId before async validation and skip diagnostics if model version has changed, preventing updates for stale models. Updated DocumentSymbolAdapter to always map symbols through toDocumentSymbol(item). Fixed missing newline in actionList.js.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(monaco): address timing issue in validation patch' directly and specifically references the main change in the PR: addressing a timing issue in the monaco validation patch, which aligns with the primary modification in patches/monaco-editor.patch.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch topic/monaco-validation-timing

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@johnyanarella johnyanarella force-pushed the topic/monaco-validation-timing branch 3 times, most recently from 396d028 to af5de65 Compare May 1, 2026 20:32
Signed-off-by: John Yanarella <jyanarella@nvidia.com>
@johnyanarella johnyanarella force-pushed the topic/monaco-validation-timing branch from af5de65 to 1a5fec0 Compare May 1, 2026 20:35
@johnyanarella johnyanarella changed the title chore(ci): fix flaky monaco validation test fix(monaco): address timing issue in validation patch May 1, 2026
@johnyanarella johnyanarella marked this pull request as ready for review May 1, 2026 20:51
@johnyanarella johnyanarella requested a review from coryrylan May 1, 2026 20:51
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
patches/monaco-editor.patch (3)

804-806: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Wrong model event method is invoked (runtime TypeError risk).

Line 805 calls model.onDidValidateModelVersion(listener), but the added model API is onDidValidateVersion(listener) (see Lines 757-767). This will fail at runtime.

Suggested fix
 export function onDidValidateModelVersion(model, listener) {
-    return model.onDidValidateModelVersion(listener);
+    return model.onDidValidateVersion(listener);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@patches/monaco-editor.patch` around lines 804 - 806, The wrapper function
onDidValidateModelVersion incorrectly calls a non-existent model method; change
the call inside onDidValidateModelVersion to invoke the model's actual API
onDidValidateVersion(listener) so the wrapper delegates to
model.onDidValidateVersion and avoids the runtime TypeError.

241-253: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Delayer.cancel() now leaves pending promises unresolved.

On Line 253, completionPromise is nulled without resolving/rejecting it. Any caller awaiting the previous trigger() promise can hang indefinitely.

Suggested fix
 cancel() {
     this.cancelTimeout();
     if (this.completionPromise) {
-        // this.doReject?.(new CancellationError());
+        // Treat cancellation as a normal completion to avoid unhandled rejections.
+        this.doResolve?.(undefined);
+        this.doResolve = null;
+        this.doReject = null;
         this.completionPromise = null;
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@patches/monaco-editor.patch` around lines 241 - 253, Delayer.cancel()
currently clears completionPromise without resolving or rejecting it, which can
leave callers awaiting trigger() hanging; restore proper completion by invoking
the stored rejection/resolution callback when canceling: in the Delayer.cancel
method call this.doReject?.(new CancellationError()) or
this.doResolve?.(undefined) as appropriate before setting completionPromise =
null so any pending promise from trigger() completes, and ensure you reference
the existing symbols this.doReject, this.doResolve, completionPromise, and the
trigger() workflow when making the change.

951-962: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

TypeScript diagnostics still applies stale markers for newer model versions.

You capture modelVersionId (Line 943) but do not compare it before setModelMarkers (Line 955). If content changes during async validation, stale diagnostics can still be rendered.

Suggested fix
 if (model.isDisposed()) {
   return;
 }
 // PATCH: Don't apply model markers if the language has changed. (Aligns this behavior with other language services.) 
 if (model.getLanguageId() !== this._selector) {
   return;
 }
+if (model.getVersionId() !== modelVersionId) {
+  return;
+}
 editor.setModelMarkers(
   model,
   this._selector,
   diagnostics.map((d) => this._convertDiagnostics(model, d))
 );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@patches/monaco-editor.patch` around lines 951 - 962, The patch must avoid
applying stale diagnostics by verifying the model version before updating
markers: before calling editor.setModelMarkers and
editor.setModelVersionValidated, compare the captured modelVersionId with the
model's current version (e.g., model.getVersionId()) and early-return if they
differ; ensure you still check the language mismatch (model.getLanguageId() !==
this._selector) first, and only call setModelMarkers(this._selector,
diagnostics.map(d => this._convertDiagnostics(model, d))) and
editor.setModelVersionValidated(model, modelVersionId) when the modelVersionId
matches the model's current version.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@patches/monaco-editor.patch`:
- Around line 804-806: The wrapper function onDidValidateModelVersion
incorrectly calls a non-existent model method; change the call inside
onDidValidateModelVersion to invoke the model's actual API
onDidValidateVersion(listener) so the wrapper delegates to
model.onDidValidateVersion and avoids the runtime TypeError.
- Around line 241-253: Delayer.cancel() currently clears completionPromise
without resolving or rejecting it, which can leave callers awaiting trigger()
hanging; restore proper completion by invoking the stored rejection/resolution
callback when canceling: in the Delayer.cancel method call this.doReject?.(new
CancellationError()) or this.doResolve?.(undefined) as appropriate before
setting completionPromise = null so any pending promise from trigger()
completes, and ensure you reference the existing symbols this.doReject,
this.doResolve, completionPromise, and the trigger() workflow when making the
change.
- Around line 951-962: The patch must avoid applying stale diagnostics by
verifying the model version before updating markers: before calling
editor.setModelMarkers and editor.setModelVersionValidated, compare the captured
modelVersionId with the model's current version (e.g., model.getVersionId()) and
early-return if they differ; ensure you still check the language mismatch
(model.getLanguageId() !== this._selector) first, and only call
setModelMarkers(this._selector, diagnostics.map(d =>
this._convertDiagnostics(model, d))) and editor.setModelVersionValidated(model,
modelVersionId) when the modelVersionId matches the model's current version.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 080dd354-869a-4628-a0b5-3259afb4be40

📥 Commits

Reviewing files that changed from the base of the PR and between 76e5b06 and 1a5fec0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • package.json
  • patches/monaco-editor.patch

+ // PATCH: Enable workers to communicate that syntax validation is complete for a specific model version
+ const model = editor.getModel(resource);
+ if (!model) {
+ return;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bail out if async validation arrives here after the model is disposed.

+ if (!model) {
+ return;
+ }
+ const modelVersionId = model.getVersionId();
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capture the versionId at the time of the validation request (this mirrors the unpatched behavior of the separate typescript code path).

+ if (model && !model.isDisposed() && model.getLanguageId() === languageId) {
+ // PATCH: Gracefully handle the case where the model changed or was disposed during async validation.
+ if (model && !model.isDisposed() && model.getLanguageId() === languageId && model.getVersionId() === modelVersionId) {
editor.setModelMarkers(model, languageId, markers);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bail out if the version of the model has advanced since validation starts (this mirrors the unpatched behavior of the separate typescript code path).

@johnyanarella johnyanarella merged commit 1ac01cb into main May 1, 2026
8 checks passed
@johnyanarella johnyanarella deleted the topic/monaco-validation-timing branch May 1, 2026 21:05
@coryrylan
Copy link
Copy Markdown
Collaborator

🎉 This issue has been resolved in version 0.0.9 🎉

Changelog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants